/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.weso.acota.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import opennlp.tools.lang.spanish.PosTagger;
import opennlp.tools.lang.spanish.SentenceDetector;
import opennlp.tools.sentdetect.SentenceDetectorME;
import opennlp.tools.tokenize.SimpleTokenizer;

import org.apache.log4j.Logger;
import org.apache.tika.language.LanguageIdentifier;
import org.weso.acota.to.ProviderTO;
import org.weso.acota.to.RequestSuggestionTO;
import org.weso.acota.to.SuggestionTO;

/**
 *
 * @author weena
 */
public class SuggestNplDAOImpl implements SuggestDAO {

	protected static Logger logger = Logger.getLogger(SuggestNplDAOImpl.class);
	private static ProviderTO provider = new ProviderTO("OpenNPL tagger");
	private RequestSuggestionTO request;
	private SuggestionTO suggest;
	private int MaxWeight;
	private ArrayList<String> pronouns = new ArrayList<String>();
	private ArrayList<String> verbs = new ArrayList<String>();
	private ArrayList<String> numbers = new ArrayList<String>();
	
	public SuggestionTO suggest(RequestSuggestionTO doRequest) {
    	logger.debug("Initialize variables");
        request = doRequest;
        suggest = request.getSuggestions();
        suggest.setResource(request.getResource());       
       
        try{
     	   AnalysisOfTerms(request.getResource().getLabel());
        }catch (Exception e) {
     	   logger.error("Error in NLP for label", e);
        } 
       
       try{
    	   AnalysisOfTerms(request.getResource().getDescription());
       }catch (Exception e) {
    	   logger.error("Error in NLP for description", e);
       }
       
       
               
        return suggest;
    }
	
	@SuppressWarnings("rawtypes")
	public void MaxValue(Map<String, Integer> labels){
		Iterator itr = suggest .getLabels().entrySet().iterator();
		while (itr.hasNext()) {
			Map.Entry e = (Map.Entry)itr.next();
			if(MaxWeight < (Integer) e.getValue()){
				MaxWeight = (Integer) e.getValue();
			}
		}
	}
	
	public void findAndRemove(String word){
		logger.debug("Remove some tags");
		if( suggest.getLabels().containsKey(word.toLowerCase())){
			logger.debug("Removing"+suggest.getLabels().size());
			suggest.getLabels().remove(word.toLowerCase());
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void findAndChangePronouns(List<String> words){
		MaxValue(suggest.getLabels());
		int sum = MaxWeight/2;
		Iterator itr = suggest .getLabels().entrySet().iterator();
		while (itr.hasNext()) {
			Map.Entry e = (Map.Entry)itr.next();
			if(words.contains(e.getKey())){
				logger.debug("Modify pronoun: "+e.getKey());
				e.setValue((Integer) e.getValue() + sum);
			}
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void findAndChangeVerbs(List<String> words){
		MaxValue(suggest.getLabels());
		int sum = MaxWeight/2;
		Iterator itr = suggest .getLabels().entrySet().iterator();
		while (itr.hasNext()) {
			Map.Entry e = (Map.Entry)itr.next();
			if(words.contains(e.getKey())){
				logger.debug("Modify verbs: "+e.getKey());
				e.setValue((Integer) e.getValue() - sum);
			}
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void findAndChangeNumbers(List<String> words){
		MaxValue(suggest.getLabels());
		Iterator itr = suggest .getLabels().entrySet().iterator();
		while (itr.hasNext()) {
			Map.Entry e = (Map.Entry)itr.next();
			if(words.contains(e.getKey())){
				logger.debug("Modify numbers: "+e.getKey());
				e.setValue((Integer) e.getValue() - MaxWeight);
			}
		}
	}
	
	public void AnalysisOfTerms(String terms){
		LanguageIdentifier ld = new LanguageIdentifier(terms);
        
        if(!ld.getLanguage().equals("en")){
        	//Tokenizer
        	SimpleTokenizer tokenizer = new SimpleTokenizer();
        	PosTagger spost = new PosTagger("/etc/acota/config/SpanishPOS.bin");
    		//spanish get sentences
        	try{
        		logger.debug("make spanish sentences detector");
            	SentenceDetectorME sentencesDetector = 
            		new SentenceDetector("/etc/acota/config/SpanishSent.bin"); 
            	String sentences [] = sentencesDetector.sentDetect(suggest.getResource().getDescription());
            	for (int i=0; i< sentences.length; i++){
            		//System.out.println(i+"-->"+sentences[i]);
            		String [] textTokenixed = tokenizer.tokenize(sentences[i]);
            		String[] tagged = spost.tag(textTokenixed);
            		for (int y=0; y< textTokenixed.length; y++){
            			//remove tag's
            			if(tagged[y].equals("DA") /* la, el, los, las*/
            			|| tagged[y].equals("SPC") /* del, al*/	
            			|| tagged[y].equals("P") /* se */
            			|| tagged[y].equals("DI") /* un, unos otros otras ... */
            			|| tagged[y].equals("PR") /* que cuyo ... */
            			|| tagged[y].equals("CC") /* y o e pero */
            			|| tagged[y].equals("PP") /* el ello lo */
            			|| tagged[y].equals("CS") /* que como pues */
            			|| tagged[y].equals("DD") /* esa, este, ese */
            			|| tagged[y].equals("DP") /* su, sus */
            			|| tagged[y].equals("RG") /* ya, mas, frente, además, unicamente... */
            			|| tagged[y].equals("AO") /* primeros, terceros, últimas */
            			|| tagged[y].equals("SPS") /*de, para, en, sobre, con ... */
            			|| tagged[y].equals("AQ") /*adjetivos calificativos */
            			|| tagged[y].equals("W") /* mayo, marzo, 2012, V, II */
            			|| tagged[y].equals("DN") /* ambos, cuarto, medio, quinto */
            			|| tagged[y].equals("PD") /* estos, este, estas, & */
            			|| tagged[y].equals("PI") /* además, uno, algunos */
            			|| tagged[y].equals("PN") /* medio,  ) */
            			|| tagged[y].equals("PT") /* qué,cómo, cuáles */
            			|| tagged[y].equals("RN") /* no */
            			|| tagged[y].equals("Y") /* cloud */
            			|| tagged[y].equals("DT") /* ++ */
            			|| tagged[y].equals("I") /* earth, wactch */
            			|| tagged[y].equals("DE") /* acute, adem, & */
            			){
            				findAndRemove(textTokenixed[y]);
            			}else{
            				if(!tagged[y].startsWith("N") && !tagged[y].startsWith("V") && !tagged[y].startsWith("F") && !tagged[y].startsWith("Z") ){
            					System.out.println(y+"-->"+textTokenixed[y]+"/"+tagged[y]);
            				}
            				
            			}
            			
            			//take all pronouns
            			if(tagged[y].startsWith("N")){
            				pronouns.add(textTokenixed[y].toLowerCase());
            			}
            			
            			//take all verbs
            			if(tagged[y].startsWith("V")){
            				verbs.add(textTokenixed[y].toLowerCase());
            			}
            			
            			//take all numbers
            			if(tagged[y].startsWith("Z")){
            				logger.debug("get numbers: "+textTokenixed[y]);
            				numbers.add(textTokenixed[y].toLowerCase());
            			}
                	}
            	}
            	
        	}catch (Exception e) {
				logger.error("Sentences detector", e);
			}
    	}
        
        findAndChangePronouns(pronouns);
        findAndChangeVerbs(verbs);
        findAndChangeNumbers(numbers); 
	}

	public ProviderTO getProvider() {
		logger.debug("Display provider name");
		return provider;
	}

}
